package com.canaan.business.service.storehouse.impl;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import com.canaan.business.common.enums.basic.YNEnum;
import com.canaan.business.domain.storehouse.StockCheck;
import com.canaan.business.domain.storehouse.StockCheckPlanDetail;
import com.canaan.business.domain.vo.CheckPlanAddVo;
import com.canaan.business.service.storehouse.*;
import com.canaan.common.exception.ServiceException;
import com.canaan.common.utils.DateUtils;
import com.canaan.common.utils.SecurityUtils;
import com.canaan.common.utils.TableNoUtil;
import com.canaan.common.utils.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import com.canaan.business.mapper.storehouse.StockCheckPlanMapper;
import com.canaan.business.domain.storehouse.StockCheckPlan;
import org.springframework.transaction.annotation.Transactional;

/**
 * 库存盘点计划Service业务层处理
 *
 * @author ruoyi
 * @date 2023-02-14
 */
@Service
public class StockCheckPlanServiceImpl implements IStockCheckPlanService {
    @Resource
    private StockCheckPlanMapper stockCheckPlanMapper;
    @Resource
    private IWmsStorehouseStockService storehouseStockService;
    @Resource
    private IStockCheckService stockCheckService;
    @Resource
    private IStockCheckPlanDetailService stockCheckPlanDetailService;

    /**
     * 查询库存盘点计划
     *
     * @param id 库存盘点计划主键
     * @return 库存盘点计划
     */
    @Override
    public StockCheckPlan selectStockCheckPlanById(Long id) {
        return stockCheckPlanMapper.selectStockCheckPlanById(id);
    }

    /**
     * 查询库存盘点计划列表
     *
     * @param stockCheckPlan 库存盘点计划
     * @return 库存盘点计划
     */
    @Override
    public List<StockCheckPlan> selectStockCheckPlanList(StockCheckPlan stockCheckPlan) {
        return stockCheckPlanMapper.selectStockCheckPlanList(stockCheckPlan);
    }

    /**
     * 新增库存盘点计划
     *
     * @param stockCheckPlan 库存盘点计划
     * @return 结果
     */
    @Override
    public int insertStockCheckPlan(StockCheckPlan stockCheckPlan) {
        if (StringUtils.isBlank(stockCheckPlan.getNo())) {
            stockCheckPlan.setNo(TableNoUtil.getNo(StockCheckPlan.class));
        }
        stockCheckPlan.setCreateBy(SecurityUtils.getUsername());
        stockCheckPlan.setCreateTime(DateUtils.getNowDate());
        return stockCheckPlanMapper.insertStockCheckPlan(stockCheckPlan);
    }

    /**
     * 批量新增库存盘点计划
     *
     * @param stockCheckPlanList 库存盘点计划列表
     * @return 结果
     */
    @Override
    public int batchInsertStockCheckPlan(List<StockCheckPlan> stockCheckPlanList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (StockCheckPlan stockCheckPlan : stockCheckPlanList) {
            if (StringUtils.isBlank(stockCheckPlan.getNo())) {
                stockCheckPlan.setNo(TableNoUtil.getNo(StockCheckPlan.class));
            }
            stockCheckPlan.setCreateBy(username);
            stockCheckPlan.setCreateTime(currerTime);
        }
        int insertNum = 0;
        for (int i = 0; i < stockCheckPlanList.size(); ) {
            int endIndex = i + 500;
            if (endIndex > stockCheckPlanList.size()) {
                endIndex = stockCheckPlanList.size();
            }
            insertNum = insertNum + stockCheckPlanMapper.batchInsertStockCheckPlan(stockCheckPlanList.subList(i, endIndex));
            i = endIndex;
        }
        return insertNum;
    }

    /**
     * 修改库存盘点计划
     *
     * @param stockCheckPlan 库存盘点计划
     * @return 结果
     */
    @Override
    public int updateStockCheckPlan(StockCheckPlan stockCheckPlan) {
        stockCheckPlan.setUpdateBy(SecurityUtils.getUsername());
        stockCheckPlan.setUpdateTime(DateUtils.getNowDate());
        return stockCheckPlanMapper.updateStockCheckPlan(stockCheckPlan);
    }

    /**
     * 批量修改库存盘点计划
     *
     * @param stockCheckPlanList 库存盘点计划列表
     * @return 结果
     */
    @Override
    public int batchUpdateStockCheckPlan(List<StockCheckPlan> stockCheckPlanList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (StockCheckPlan stockCheckPlan : stockCheckPlanList) {
            stockCheckPlan.setUpdateBy(username);
            stockCheckPlan.setUpdateTime(currerTime);
        }
        int updateNum = 0;
        for (int i = 0; i < stockCheckPlanList.size(); ) {
            int endIndex = i + 500;
            if (endIndex > stockCheckPlanList.size()) {
                endIndex = stockCheckPlanList.size();
            }
            updateNum = updateNum + stockCheckPlanMapper.batchUpdateStockCheckPlan(stockCheckPlanList.subList(i, endIndex));
            i = endIndex;
        }
        return updateNum;
    }

    /**
     * 批量删除库存盘点计划
     *
     * @param ids 需要删除的库存盘点计划主键集合
     * @return 结果
     */
    @Override
    public int deleteStockCheckPlanByIds(Long[] ids) {
        return stockCheckPlanMapper.deleteStockCheckPlanByIds(ids);
    }

    /**
     * 删除库存盘点计划信息
     *
     * @param id 库存盘点计划主键
     * @return 结果
     */
    @Override
    public int deleteStockCheckPlanById(Long id) {
        return stockCheckPlanMapper.deleteStockCheckPlanById(id);
    }

    /**
     * 查询库存盘点计划
     *
     * @param no 编号
     * @return 库存盘点计划
     */
    @Override
    public StockCheckPlan selectStockCheckPlanByNo(String no) {
        return stockCheckPlanMapper.selectStockCheckPlanByNo(no);
    }

    /**
     * 批量删除库存盘点计划
     *
     * @param nos 需要删除的编号集合
     * @return 结果
     */
    @Override
    public int deleteStockCheckPlanByNos(String[] nos) {
        return stockCheckPlanMapper.deleteStockCheckPlanByNos(nos);
    }

    /**
     * 删除库存盘点计划信息
     *
     * @param no 编号
     * @return 结果
     */
    @Override
    public int deleteStockCheckPlanByNo(String no) {
        return stockCheckPlanMapper.deleteStockCheckPlanByNo(no);
    }

    @Override
    @Transactional
    public int generator(Long[] ids) {
        for (Long id : ids) {
            StockCheckPlan stockCheckPlan = this.selectStockCheckPlanById(id);
            if (stockCheckPlan == null) {
                throw new ServiceException("无效ID");
            }
            if (YNEnum.Y.getCode().equals(stockCheckPlan.getIsGenerator())) {
                throw new ServiceException("计划" + stockCheckPlan.getName() + "已生成盘点任务");
            }
            if (stockCheckPlan.getStartTime() != null && DateUtil.compare(new Date(), stockCheckPlan.getStartTime()) != 1) {
                throw new ServiceException("计划" + stockCheckPlan.getName() + "未到计划开始时间");
            }
            stockCheckPlan.setIsGenerator(YNEnum.Y.getCode());
            this.updateStockCheckPlan(stockCheckPlan);
            //生成盘点任务
            StockCheck stockCheck = stockCheckService.generatorByPlan(stockCheckPlan);
            //锁定库存
            stockCheckService.checkLock(stockCheck,null);
        }

        return 1;
    }

    @Override
    @Transactional
    public int addWithDetail(CheckPlanAddVo checkPlanAddVo) {
        StockCheckPlan stockCheckPlan = BeanUtil.toBean(checkPlanAddVo, StockCheckPlan.class);
        List<StockCheckPlanDetail> stockCheckPlanDetailList = checkPlanAddVo.getStockCheckPlanDetailList();
        if (checkPlanAddVo.getId() == null) {
            this.insertStockCheckPlan(stockCheckPlan);
            if (CollUtil.isNotEmpty(stockCheckPlanDetailList)) {
                stockCheckPlanDetailList.stream().forEach(e -> e.setPlanNo(stockCheckPlan.getNo()));
                this.stockCheckPlanDetailService.batchInsertStockCheckPlanDetail(stockCheckPlanDetailList);
            }
        } else {
            this.updateStockCheckPlan(stockCheckPlan);
            StockCheckPlanDetail detail = new StockCheckPlanDetail();
            detail.setPlanNo(stockCheckPlan.getNo());
            List<StockCheckPlanDetail> stockCheckPlanDetails = this.stockCheckPlanDetailService.selectStockCheckPlanDetailList(detail);
            List<Long> ids = stockCheckPlanDetails.stream().map(e -> e.getId()).collect(Collectors.toList());

            List<StockCheckPlanDetail> addList = stockCheckPlanDetailList.stream().filter(e -> e.getId() == null).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(addList)) {
                this.stockCheckPlanDetailService.batchInsertStockCheckPlanDetail(addList);
            }

            List<StockCheckPlanDetail> updateList = stockCheckPlanDetailList.stream().filter(e -> e.getId() != null).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(updateList)) {
                this.stockCheckPlanDetailService.batchUpdateStockCheckPlanDetail(updateList);
            }

            ids.removeAll(addList.stream().map(e -> e.getId()).collect(Collectors.toList()));
            ids.removeAll(updateList.stream().map(e -> e.getId()).collect(Collectors.toList()));
            if (CollUtil.isNotEmpty(ids)) {
                this.stockCheckPlanDetailService.deleteStockCheckPlanDetailByIds(ArrayUtil.toArray(ids, Long.class));
            }
        }
        return 1;
    }
}
